/******************************************************************************\
 * Filename   : enc_aenc.c
 * Copyright  : 
 * Created    : 2018-10-31 by litao
 * Description:
 * 
\******************************************************************************/
#include "enc_vi.h"
#include "enc_aenc.h"
#include "audio_aac_adp.h"

/******************************************************************************
* function : Start Aenc
******************************************************************************/
HI_S32 enc_aenc_start(int chan_num, stENC_AUDSET *p_audioSet)
{
    AENC_CHN AeChn;
    HI_S32 s32Ret;
    AENC_CHN_ATTR_S stAencAttr;
    AENC_ATTR_AAC_S stAencAac;
	AIO_ATTR_S stAioAttr;
	AIO_ATTR_S *pstAioAttr;

	enc_ai_set_attr(&stAioAttr);
	pstAioAttr = &stAioAttr;
	
    /* set AENC chn attr */
    stAencAttr.enType = PT_AAC;
    stAencAttr.u32BufSize = 30;
    stAencAttr.u32PtNumPerFrm = pstAioAttr->u32PtNumPerFrm;
    
	if (PT_AAC == stAencAttr.enType)
    {
        stAencAttr.pValue = &stAencAac;
        stAencAac.enAACType = AAC_TYPE_AACLC;
        stAencAac.enBitRate = AAC_BPS_128K; //p_audioSet->aud_bitrate_kb*1000;
        stAencAac.enBitWidth = AUDIO_BIT_WIDTH_16;
        stAencAac.enSmpRate = pstAioAttr->enSamplerate;
        stAencAac.enSoundMode = pstAioAttr->enSoundmode;
        stAencAac.enTransType = AAC_TRANS_TYPE_ADTS;
        stAencAac.s16BandWidth = 0;
    }
    else
    {
        printf("%s: invalid aenc payload type:%d\n", __FUNCTION__, stAencAttr.enType);
        return HI_FAILURE;
    }    
	s32Ret = HI_MPI_AENC_AacInit();
	if (HI_SUCCESS != s32Ret)
	{
		printf("%s: aac aenc init failed with %d!\n", __FUNCTION__, s32Ret);
		return HI_FAILURE;
	}

           
    AeChn = chan_num;
    
    /* create aenc chn*/
    s32Ret = HI_MPI_AENC_CreateChn(AeChn, &stAencAttr);
    if (HI_SUCCESS != s32Ret)
    {
        printf("%s: HI_MPI_AENC_CreateChn(%d) failed with %#x!\n", __FUNCTION__, AeChn, s32Ret);
        return s32Ret;
    }        

    return HI_SUCCESS;
}

/******************************************************************************
* function : Stop Aenc
******************************************************************************/
HI_S32 enc_aenc_stop(int chan_num)
{
    HI_S32 s32Ret;
    
    s32Ret = HI_MPI_AENC_DestroyChn(chan_num);
    if (HI_SUCCESS != s32Ret)
    {
        printf("%s: HI_MPI_AENC_DestroyChn(%d) failed with %#x!\n", __FUNCTION__,
               chan_num, s32Ret);
        return s32Ret;
    }
    
    return HI_SUCCESS;
}

int enc_aenc_send_frame(int chan_num)
{
	int ret;
	enc_ai_queue *p_ai_queue;
	AUDIO_FRAME_SS *p_frame;
	AUDIO_FRAME_S audio_frame; 

	p_ai_queue = &main_data.p_ai_block->queue[chan_num];
	sem_wait(p_ai_queue->p_lock);
	while (p_ai_queue->read_pos != p_ai_queue->write_pos) {
		memset(&audio_frame, 0, sizeof(audio_frame));
		p_frame = (AUDIO_FRAME_SS *)p_ai_queue->frame_buffer[p_ai_queue->read_pos];
		audio_frame.enBitwidth = p_frame->enBitwidth;
		audio_frame.enSoundmode = p_frame->enSoundmode;
		audio_frame.u64TimeStamp = p_frame->u64TimeStamp;
		audio_frame.u32Seq = p_frame->u32Seq;
		audio_frame.u32Len = p_frame->u32Len;
		audio_frame.pVirAddr[0] = p_frame->data;

        ret = HI_MPI_AENC_SendFrame(chan_num, &audio_frame, NULL);
        if (HI_SUCCESS != ret)
        {
            printf("%s: HI_MPI_AENC_SendFrame(%d), failed with %#x!\n", __FUNCTION__, chan_num, ret);
			break;
        }		
	}
	sem_post(p_ai_queue->p_lock);

	return 0;
}

void *enc_audio_input(void *p_arg)
{
	int ret;
	stENC_AUDSET *p_audioSet = &g_encset_slv->enc_chls[main_data.chan_srcnum].encchl_aud;

	ret = enc_ai_mem_init();
	if (ret < 0) {
		return NULL;
	}	

	ret = enc_aenc_start(main_data.chan_mapnum, p_audioSet);
	if (ret != 0) {
		enc_err("enc_aenc_start error\n");
		return NULL;
	}

	while (1) {
		enc_aenc_send_frame(main_data.chan_mapnum);
		usleep(10000);
	}

	enc_aenc_stop(main_data.chan_mapnum);
	enc_ai_mem_uninit();

	return NULL;
}

